package com.wyix;

import com.wyix.entity.Message;
import com.wyix.entity.Product;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 在电商系统中，商品列表需要频繁展示给用户，因此需要快速访问商品信息。这里使用 ArrayList 来存储商品信息。
 *
 * @author wangdx
 * @since 2025/8/1
 */
public class EcommerceExample {
    public static void main(String[] args) {
        // 使用 ArrayList 存储商品信息
        List<Product> products = new ArrayList<>();
        products.add(new Product(1, "手机", 2999.99));
        products.add(new Product(2, "电脑", 5999.99));
        products.add(new Product(3, "平板", 3999.99));

        // 展示商品列表
        System.out.println("商品列表：");
        for (int i = 0; i < products.size(); i++) {
            Product product = products.get(i);
            System.out.println("商品 ID：" + product.getId() + "，名称：" + product.getName() + "，价格：" + product.getPrice());
        }

        //为了快速根据商品 ID 查找商品信息，我们使用 HashMap 来建立映射关系。
        /*HashMap 的查询、添加、删除操作平均时间复杂度为 O(1)，能快速根据商品 ID 找到对应的商品信息。*/
        // 使用 HashMap 存储商品 ID 到商品信息的映射
        Map<Long, Product> productMap = new HashMap<>();
        productMap.put(1L, new Product(1, "手机", 2999.99));
        productMap.put(2L, new Product(2, "电脑", 5999.99));
        productMap.put(3L, new Product(3, "平板", 3999.99));

        // 根据商品 ID 查询商品信息
        long productId = 2L;
        Product product = productMap.get(productId);
        if (product != null) {
            System.out.println("查询到商品：" + product.getName());
        }

        // 使用 ConcurrentHashMap 作为商品搜索缓存
        ConcurrentMap<String, Product> searchCache = new ConcurrentHashMap<>();

        // 线程 1：添加搜索结果到缓存
        new Thread(() -> {
            Product searchResult = new Product(4, "耳机", 299.99);
            searchCache.put("耳机", searchResult);
        }).start();

        // 线程 2：从缓存中查询商品
        new Thread(() -> {
            String searchKeyword = "耳机";
            Product cachedProduct = searchCache.get(searchKeyword);
            if (cachedProduct != null) {
                System.out.println("从缓存中查询到商品：" + cachedProduct.getName());
            }
        }).start();

        // 使用 HashSet 记录用户兴趣标签
        Set<String> userTags = new HashSet<>();
        userTags.add("音乐");
        userTags.add("电影");
        userTags.add("游戏");
        userTags.add("音乐"); // 重复元素，不会被添加

        // 展示用户兴趣标签
        System.out.println("用户兴趣标签：");
        for (String tag : userTags) {
            System.out.println("- " + tag);
        }

        // 使用 LinkedHashMap 实现 LRU 缓存
        // LinkedHashMap 可以保持元素的访问顺序，当缓存满时，自动删除最久未使用的元素。
        int maxSize = 3;
        Map<String, Product> browsingHistory = new LinkedHashMap<String, Product>(maxSize, 0.75f, true) {
            @Override
            protected boolean removeEldestEntry(Map.Entry<String, Product> eldest) {
                return size() > maxSize;
            }
        };

        browsingHistory.put("手机", new Product(1, "手机", 2999.99));
        browsingHistory.put("电脑", new Product(2, "电脑", 5999.99));
        browsingHistory.put("平板", new Product(3, "平板", 3999.99));
        System.out.println("浏览历史：" + browsingHistory.keySet());

        browsingHistory.get("手机"); // 访问手机，使其成为最近使用的元素
        System.out.println("浏览历史：" + browsingHistory.keySet());

        browsingHistory.put("耳机", new Product(4, "耳机", 299.99)); // 添加新元素，超过 maxSize，最久未使用的电脑会被删除
        System.out.println("浏览历史：" + browsingHistory.keySet());


        // 使用 TreeMap 按商品价格排序
        // TreeMap 可以保证键的有序性，适合需要对商品价格进行排序的场景。
        Map<Double, Product> priceMap = new TreeMap<>();
        priceMap.put(2999.99, new Product(1, "手机", 2999.99));
        priceMap.put(5999.99, new Product(2, "电脑", 5999.99));
        priceMap.put(3999.99, new Product(3, "平板", 3999.99));

        // 按价格从低到高展示商品
        System.out.println("商品按价格排序：");
        for (Map.Entry<Double, Product> entry : priceMap.entrySet()) {
            System.out.println("价格：" + entry.getKey() + "，商品：" + entry.getValue().getName());
        }

        // 使用 LinkedList 作为消息队列
        // LinkedList 适合频繁在集合头部和尾部进行添加、删除操作的场景，可作为消息队列使用。
        Queue<Message> messageQueue = new LinkedList<>();

        // 生产消息（添加到队列尾部）
        messageQueue.offer(new Message("M001", "订单创建成功"));
        messageQueue.offer(new Message("M002", "支付成功"));
        messageQueue.offer(new Message("M003", "订单发货"));

        // 消费消息（从队列头部获取并删除）
        System.out.println("消费订单消息：");
        while (!messageQueue.isEmpty()) {
            Message message = messageQueue.poll();
            System.out.println("消费消息：" + message.getContent());
        }
    }
}
